#include <stdio.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <fcntl.h>
#include "time.h"

#define uint32_t  unsigned int

struct SpiMsg {
    unsigned char *wbuf;       /**< Address of the write buffer */
    unsigned char *rbuf;       /**< Address of the read buffer */
    uint32_t len;        /**< Length of the read and write buffers. The read buffer and the write
                          * buffer have the same length.
                          */
    uint32_t speed;      /**< Current message transfer speed */
    unsigned short delayUs;    /**< Delay (in microseconds) before starting the next transfer.
                          * The value <b>0</b> indicates there is no delay between transfers.
                          */
    unsigned char keepCs;    /**< Whether to keep CS active after current transfer has been
                          * completed. <b>1</b> indicates to keeps CS; <b>0</b> indicates to switch off the CS.
                          */
};

struct SpiIocMsg {
    struct SpiMsg *msg;
    int count;
};

#define SPI_CPHA		0x01
#define SPI_CPOL		0x02

#define SPI_MODE_0		(0|0)
#define SPI_MODE_1		(0|SPI_CPHA)
#define SPI_MODE_2		(SPI_CPOL|0)
#define SPI_MODE_3		(SPI_CPOL|SPI_CPHA)

#define SPI_IOC_MAGIC 'k'
#define SPI_IOC_MESSAGE                 _IOW(SPI_IOC_MAGIC, 0, struct SpiIocMsg)
#define SPI_IOC_RD_MODE                 _IOR(SPI_IOC_MAGIC, 1, uint32_t)
#define SPI_IOC_RD_LSB_FIRST            _IOR(SPI_IOC_MAGIC, 2, uint32_t)
#define SPI_IOC_RD_BITS_PER_WORD        _IOR(SPI_IOC_MAGIC, 3, uint32_t)
#define SPI_IOC_RD_MAX_SPEED_HZ         _IOR(SPI_IOC_MAGIC, 4, uint32_t)
#define SPI_IOC_WR_MODE                 _IOW(SPI_IOC_MAGIC, 1, uint32_t)
#define SPI_IOC_WR_LSB_FIRST            _IOW(SPI_IOC_MAGIC, 2, uint32_t)
#define SPI_IOC_WR_BITS_PER_WORD        _IOW(SPI_IOC_MAGIC, 3, uint32_t)
#define SPI_IOC_WR_MAX_SPEED_HZ         _IOW(SPI_IOC_MAGIC, 4, uint32_t)

//spidev0.0
#define DEV_NAME "/dev/spidev2.0"



int main(int argc, char **argv)
{
    printf("\n************************************************\n");
    int fd = 0;
    int ret = 0;
    int i = 0;

    fd = open(DEV_NAME, O_RDWR);
    if(fd == 0){
        printf("open %s failed error: %d\n",DEV_NAME, fd);
        return -1;
    }else{
        printf("open %s sucess fd: %d\n",DEV_NAME, fd);
    }
    unsigned long arg = SPI_MODE_3;
    ioctl(fd, SPI_IOC_WR_MODE, &arg);
    arg = 10000000; 
    ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &arg);//设置传输频率

    unsigned char wbuf[8] = {0xD0, 0x00, 0x00, 0x00, 0x00};
    unsigned char rbuf[8] = {0x00};

    struct SpiIocMsg iocmsg = {0};
    struct SpiMsg msg = {0};
    msg.wbuf = wbuf;
    msg.rbuf = rbuf;
    msg.len = 2;
    msg.speed = 10000000;
    iocmsg.msg = &msg;
    iocmsg.count = 1;
    
    ioctl(fd, SPI_IOC_MESSAGE, &iocmsg);
    for ( i = 0; i < 8; i++)
    {
        printf("%x ", rbuf[i]);
    }
    printf("\n");
    wbuf[0] = 0xFA;
    msg.len = 6;
    ioctl(fd, SPI_IOC_MESSAGE, &iocmsg);

    printf("\n");


    close(fd);
    printf("\n************************************************\n\n");
    
    return 0;
}